package com.zxhhyj.ui.view

import android.os.Parcelable
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.material.LocalContentColor
import androidx.compose.material.LocalTextStyle
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.zxhhyj.ui.theme.LocalColorScheme
import com.zxhhyj.ui.theme.LocalDimens
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import kotlin.math.abs
import kotlin.math.roundToInt

val toolbarHeight = 56.dp

@Parcelize
class TopBarState : Parcelable, NestedScrollConnection {

    /**
     * TopBar高度
     */
    @IgnoredOnParcel
    var topBarHeight by mutableIntStateOf(0)

    /**
     * TopBar可活动的长度
     */
    @IgnoredOnParcel
    var topBarActiveLength by mutableIntStateOf(0)

    /**
     * TopBar当前偏移高度
     */
    @IgnoredOnParcel
    var tapBarOffsetHeight by mutableFloatStateOf(0f)

    /**
     * topBar偏移进度
     */
    val progress get() = abs(tapBarOffsetHeight) / topBarActiveLength

    override fun onPostScroll(
        consumed: Offset,
        available: Offset,
        source: NestedScrollSource
    ): Offset {
        val newOffset = tapBarOffsetHeight + available.y
        tapBarOffsetHeight = newOffset.coerceIn(tapBarOffsetHeight, 0f)
        return when {
            newOffset < tapBarOffsetHeight -> {
                available
            }

            newOffset > -topBarHeight -> {
                available
            }

            else -> {
                available
            }
        }
    }

    override fun onPreScroll(
        available: Offset,
        source: NestedScrollSource
    ): Offset {
        val newOffset = tapBarOffsetHeight + available.y
        return if (available.y > 0) {
            Offset.Zero
        } else {
            tapBarOffsetHeight =
                newOffset.coerceIn(-topBarActiveLength.toFloat(), tapBarOffsetHeight)
            when {
                newOffset < tapBarOffsetHeight -> {
                    Offset.Zero
                }

                newOffset > -topBarHeight -> {
                    available
                }

                else -> {
                    Offset.Zero
                }
            }
        }
    }
}

fun Modifier.bindTopBarState() = composed {
    val topBarState = LocalTopBarState.current
    nestedScroll(connection = topBarState)
        .offset {
            return@offset IntOffset(
                x = 0,
                y = (topBarState.topBarHeight + topBarState.tapBarOffsetHeight).roundToInt()
            )
        }
}

@Composable
fun AppCenterTopBar(
    modifier: Modifier = Modifier,
    title: @Composable () -> Unit = {},
    actions: (@Composable () -> Unit)? = null
) {
    val topBarState = LocalTopBarState.current
    Box(modifier = modifier
        .fillMaxWidth()
        .onSizeChanged {
            topBarState.topBarHeight = it.height
        }
        .clickable(enabled = false) {
            //用户修复点击事件穿透的问题
        }
        .background(LocalColorScheme.current.background)
        .padding(horizontal = LocalDimens.current.horizontal)
    ) {
        Box(
            modifier = Modifier
                .height(toolbarHeight)
                .fillMaxWidth(),
            contentAlignment = Alignment.Center,
            content = {
                CompositionLocalProvider(
                    LocalTextStyle provides TextStyle(
                        color = LocalColorScheme.current.text,
                        fontSize = 18.sp
                    )
                ) {
                    title()
                }
            }
        )
        Row(
            modifier = Modifier.align(Alignment.CenterEnd),
            horizontalArrangement = Arrangement.spacedBy(LocalDimens.current.horizontal / 2)
        ) {
            actions?.let {
                CompositionLocalProvider(LocalContentColor provides LocalColorScheme.current.highlight) {
                    it.invoke()
                }
            }
        }
    }
}

@Composable
fun AppTopBar(
    modifier: Modifier = Modifier,
    topBarProperties: TopBarProperties = TopBarProperties(),
    title: @Composable () -> Unit = {},
    actions: @Composable () -> Unit = {},
    content: @Composable () -> Unit = {
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = LocalDimens.current.horizontal)
                .height(toolbarHeight)
        ) {
            CompositionLocalProvider(
                LocalTextStyle provides TextStyle(
                    color = LocalColorScheme.current.text,
                    fontSize = 26.sp,
                )
            ) {
                title()
            }
        }
    }
) {
    val topBarState = LocalTopBarState.current
    var contentSize by remember {
        mutableStateOf(IntSize.Zero)
    }
    Box(modifier = modifier) {
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .onSizeChanged {
                    topBarState.topBarHeight = it.height
                    topBarState.topBarActiveLength = it.height / 2
                }) {
            Box(
                modifier = Modifier
                    .clickable(enabled = false) {
                        //用户修复点击事件穿透的问题
                    }
                    .height(toolbarHeight)
                    .fillMaxWidth()
                    .clipToBounds()
                    .background(LocalColorScheme.current.background)
                    .padding(horizontal = LocalDimens.current.horizontal),
                contentAlignment = Alignment.CenterEnd,
                content = {
                    Box(
                        modifier = Modifier
                            .fillMaxWidth()
                            .offset {
                                return@offset IntOffset(
                                    x = 0,
                                    y = (contentSize.height + topBarState.tapBarOffsetHeight)
                                        .roundToInt()
                                        .coerceIn(0, contentSize.height)
                                )
                            },
                        contentAlignment = Alignment.Center
                    ) {
                        CompositionLocalProvider(
                            LocalTextStyle provides TextStyle(
                                color = LocalColorScheme.current.text,
                                fontSize = 18.sp,
                            )
                        ) {
                            title()
                        }
                    }
                    Row(horizontalArrangement = Arrangement.spacedBy(LocalDimens.current.horizontal / 2)) {
                        CompositionLocalProvider(LocalContentColor provides LocalColorScheme.current.highlight) {
                            actions.invoke()
                        }
                    }
                }
            )
            if (topBarProperties.showDivider) {
                AppDivider(
                    modifier = Modifier
                        .fillMaxWidth()
                        .alpha(topBarState.progress)
                )
            }
            Box(modifier = Modifier
                .clipToBounds()
                .onSizeChanged {
                    contentSize = it
                }
                .offset {
                    return@offset IntOffset(
                        x = 0,
                        y = topBarState.tapBarOffsetHeight.roundToInt()
                    )
                }
                .clickable(enabled = false) {
                    //用户修复点击事件穿透的问题
                }
            ) {
                content.invoke()
            }
        }

    }
}

/**
 * @param showDivider 是否显示中间的线条
 */
class TopBarProperties(val showDivider: Boolean = true)